/** * Copyright (C) 2013-2014 Project-Vethrfolnir * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.vethrfolnir.game.network; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import com.vethrfolnir.game.network.login.LoginServerClientHandler; import com.vethrfolnir.logging.MuLogger; import com.vethrfolnir.network.*; import com.vethrfolnir.services.threads.CorvusThreadPool; import corvus.corax.Corax; import corvus.corax.config.Config; import corvus.corax.inject.Inject; /** * @author Vlad * */ public final class LoginServerClient extends NetworkClient implements NetworkServerInterface, Runnable { private static final MuLogger log = MuLogger.getLogger(LoginServerClient.class); @Config(key = "LoginServer.Host", value = "0.0.0.0") private String host; @Config(key = "LoginServer.Port", value = "8081") private int port; private Bootstrap bootstrap; private ChannelFuture channelFuture; private NetworkClient client; public LoginServerClient() { super(null); } @Inject private void load() { log.info("Preparing To connect to login! Info[Host: "+host+", Port: "+port+"]"); try { NioEventLoopGroup workerGroup = new NioEventLoopGroup(); bootstrap = new Bootstrap(); bootstrap.group(workerGroup) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast( //new LoggingHandler(LogLevel.INFO) new LoginServerClientHandler(LoginServerClient.this) ); } }); } catch(Exception e) { log.fatal("Unable to set up netty!", e); } } /* (non-Javadoc) * @see com.vethrfolnir.login.network.NetworkServerInterface#start() */ @Override public void start() { // Reload if(bootstrap == null) { load(); } Corax.fetch(CorvusThreadPool.class).executeLongRunning(this); } @Override public void stop() { if(channelFuture != null) channelFuture.channel().close(); } @Override public void run() { try { // Start the server. channelFuture = bootstrap.connect(host, port); log.info("Connected on login "+channelFuture.channel()); channelFuture.sync(); // Wait until the server socket is closed. channelFuture.channel().closeFuture().sync(); } catch(Exception e) { log.fatal("Network thread fail!", e); } finally { // Shut down all event loops to terminate all threads. bootstrap.group().shutdownGracefully(); bootstrap = null; channelFuture = null; try { log.info("Restarting!"); Thread.sleep(2000); start(); } catch (InterruptedException e) { e.printStackTrace(); } } } @Override public Channel channel() { return channelFuture.channel(); } @Override public void sendPacket(WritePacket packet, Object... params) { ByteBuf buff = client.alloc().buffer(); packet.write(client, buff, params); client.writeAndFlush(buff); } /** * @param ctx */ public void create(final ChannelHandlerContext ctx) { client = new NetworkClient(ctx.channel()) { @Override public void sendPacket(WritePacket packet, Object... params) { }}; } }